90 sfg->Accel.iWhoAmI = 0;
96 sfg->Gyro.iWhoAmI = 0;
99 sfg->Pressure.iWhoAmI = 0;
115 if (sfg && pSensor && bus_driver && initialize && read)
124 pSensor->
read = read;
126 pSensor->
addr = addr;
150 for (pSensor = sfg->
pSensors; pSensor != NULL; pSensor = pSensor->
next)
153 if (status == 0) status = s;
165 if (sfg->Accel.iFIFOExceeded > 0) {
172 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
173 for (i = 0; i < sfg->Accel.iFIFOCount; i++)
174 for (j =
CHX; j <=
CHZ; j++) iSum[j] += sfg->Accel.iGsFIFO[i][j];
175 if (sfg->Accel.iFIFOCount > 0)
177 for (j =
CHX; j <=
CHZ; j++)
179 sfg->Accel.iGs[j] = (
int16)(iSum[j] / (
int32) sfg->Accel.iFIFOCount);
180 sfg->Accel.fGs[j] = (float)sfg->Accel.iGs[j] * sfg->Accel.fgPerCount;
210 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
215 for (j =
CHX; j <=
CHZ; j++)
239 if (sfg->Gyro.iFIFOExceeded > 0) {
249 for (j =
CHX; j <=
CHZ; j++) iSum[j] = 0;
250 for (i = 0; i < sfg->Gyro.iFIFOCount; i++)
251 for (j =
CHX; j <=
CHZ; j++)
252 iSum[j] += sfg->Gyro.iYsFIFO[i][j];
253 if (sfg->Gyro.iFIFOCount > 0)
255 for (j =
CHX; j <=
CHZ; j++)
257 sfg->Gyro.iYs[j] = (
int16)(iSum[j] / (
int32) sfg->Gyro.iFIFOCount);
258 sfg->Gyro.fYs[j] = (float)sfg->Gyro.iYs[j] * sfg->Gyro.fDegPerSecPerCount;
269 uint16_t read_loop_counter
279 for (pSensor = sfg->
pSensors; pSensor != NULL; pSensor = pSensor->
next)
281 remainder = fmod(read_loop_counter, pSensor->
schedule);
283 s = pSensor->
read(pSensor, sfg);
284 if (status == 0) status = s;
298 if (sfg->Accel.isEnabled) processAccelData(sfg);
306 if (sfg->Gyro.isEnabled) processGyroData(sfg);
319 for (i=0; i<numElements; i++) d8[i]=0;
323 for (i=0; i<numElements; i++) d16[i]=0;
327 for (i=0; i<numElements; i++) d32[i]=0;
336 for (i=0; i<numElements; i++)
341 for (i=0; i<numElements; i++)
346 for (i=0; i<numElements; i++)
359 sfg->Accel.iFIFOCount=0;
360 sfg->Accel.iFIFOExceeded =
false;
367 sfg->Gyro.iFIFOCount=0;
368 sfg->Gyro.iFIFOExceeded =
false;
392 pSV_1DOF_P_BASIC = &(sfg->SV_1DOF_P_BASIC);
394 pSV_1DOF_P_BASIC = NULL;
397 pSV_3DOF_G_BASIC = &(sfg->SV_3DOF_G_BASIC) ;
399 pSV_3DOF_G_BASIC = NULL;
402 pSV_3DOF_B_BASIC = &(sfg->SV_3DOF_B_BASIC);
404 pSV_3DOF_B_BASIC = NULL;
407 pSV_3DOF_Y_BASIC = &(sfg->SV_3DOF_Y_BASIC);
409 pSV_3DOF_Y_BASIC = NULL;
412 pSV_6DOF_GB_BASIC = &(sfg->SV_6DOF_GB_BASIC);
414 pSV_6DOF_GB_BASIC = NULL;
417 pSV_6DOF_GY_KALMAN = &(sfg->SV_6DOF_GY_KALMAN);
419 pSV_6DOF_GY_KALMAN = NULL;
421 #if F_9DOF_GBY_KALMAN 422 pSV_9DOF_GBY_KALMAN = &(sfg->SV_9DOF_GBY_KALMAN);
424 pSV_9DOF_GBY_KALMAN = NULL;
427 pAccel = &(sfg->Accel);
439 pGyro = &(sfg->Gyro);
444 pPressure = &(sfg->Pressure);
452 pSV_3DOF_B_BASIC, pSV_3DOF_Y_BASIC,
453 pSV_6DOF_GB_BASIC, pSV_6DOF_GY_KALMAN,
454 pSV_9DOF_GBY_KALMAN, pAccel, pMag, pGyro,
518 if (sample[
CHX] == -32768) sample[
CHX]++;
519 if (sample[
CHY] == -32768) sample[
CHY]++;
520 if (sample[
CHZ] == -32768) sample[
CHZ]++;
530 if (fifoCount < maxFifoSize) {
void fRunMagCalibration(struct MagCalibration *pthisMagCal, struct MagBuffer *pthisMagBuffer, struct MagSensor *pthisMag, int32 loopcounter)
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
void runFusion(SensorFusionGlobals *sfg)
void fUpdateAccelBuffer(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, struct AccelSensor *pthisAccel, volatile int8 *AccelCalPacketOn)
Update the buffer used to store samples used for accelerometer calibration.
runFusion_t * runFusion
run the fusion routines
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
The PressureSensor structure stores raw and processed measurements for an altimeter.
void ApplyMagHAL(struct MagSensor *Mag)
Apply the magnetometer Hardware Abstraction Layer.
#define F_3DOF_Y_BASIC
3DOF gyro integration algorithm selector - 0x0800 to include, 0x0000 otherwise
#define CORE_SYSTICK_HZ
core and systick clock rate (Hz)
installSensor_t * installSensor
function for installing a new sensor into t
uint32_t iFlags
a bit-field of sensors and algorithms used
#define F_1DOF_P_BASIC
1DOF pressure (altitude) and temperature algorithm selector - 0x0100 to include, 0x0000 otherwise ...
int8_t() initializeSensor_t(struct PhysicalSensor *sensor, struct SensorFusionGlobals *sfg)
void conditionSample(int16_t sample[3])
conditionSample ensures that we never encounter the maximum negative two's complement value for a 16-...
struct StatusSubsystem * pStatusSubsystem
Quaternion derived from 3-axis gyro only (rotation)
#define F_USING_TEMPERATURE
nominally 0x0010 if temp sensor is to be used, 0x0000 otherwise
int32_t systick_Spare
systick counter for counts spare waiting for timing interrupt
The SV_1DOF_P_BASIC structure contains state information for a pressure sensor/altimeter.
The MagSensor structure stores raw and processed measurements for a 3-axis magnetic sensor...
Quaternion derived from 3-axis accel (tilt)
uint8_t data[FXLS8962_DATA_SIZE]
quaternion_type DefaultQuaternionPacketType
default quaternion transmitted at power on
Recoverable FAULT = something went wrong, but we can keep going.
Initializing sensors and algorithms.
An instance of PhysicalSensor structure type should be allocated for each physical sensors (combo dev...
spiSlaveSpecificParams_t slaveParams
SPI specific parameters. Not used for I2C.
uint8_t iFIFOCount
number of measurements read from FIFO
int8_t initializeSensors(SensorFusionGlobals *sfg)
int32_t systick_I2C
systick counter to benchmark I2C reads
uint16_t schedule
Parameter to control sensor sampling rate.
void initSensorFusionGlobals(SensorFusionGlobals *sfg, StatusSubsystem *pStatusSubsystem, ControlSubsystem *pControlSubsystem)
utility function to insert default values in the top level structure
uint16_t addr
I2C address if applicable.
#define F_6DOF_GB_BASIC
6DOF accel and mag eCompass algorithm selector - 0x1000 to include, 0x0000 otherwise ...
SV_6DOF_GY_KALMAN is the 6DOF Kalman filter accelerometer and gyroscope state vector structure...
int16_t iBsFIFO[MAG_FIFO_SIZE][3]
FIFO measurements (counts)
Non-recoverable FAULT = something went very wrong.
Lower level magnetic calibration interface.
struct MagBuffer MagBuffer
mag cal constellation points
This is the 3DOF basic magnetometer state vector structure/.
void fInitializeFusion(SensorFusionGlobals *sfg)
The FifoSensor union allows us to use common pointers for Accel, Mag & Gyro logical sensor structures...
#define CHX
Used to access X-channel entries in various data data structures.
setStatus_t * setStatus
change status indicator immediately
uint8_t iWhoAmI
sensor whoami
void fInitializeAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, volatile int8 *AccelCalPacketOn)
Initialize the accelerometer calibration functions.
Defines control sub-system.
int16_t iGsFIFO[ACCEL_FIFO_SIZE][3]
FIFO measurements (counts)
#define F_ALL_SENSORS
refers to all applicable sensor types for the given physical unit
void fFuseSensors(struct SV_1DOF_P_BASIC *pthisSV_1DOF_P_BASIC, struct SV_3DOF_G_BASIC *pthisSV_3DOF_G_BASIC, struct SV_3DOF_B_BASIC *pthisSV_3DOF_B_BASIC, struct SV_3DOF_Y_BASIC *pthisSV_3DOF_Y_BASIC, struct SV_6DOF_GB_BASIC *pthisSV_6DOF_GB_BASIC, struct SV_6DOF_GY_KALMAN *pthisSV_6DOF_GY_KALMAN, struct SV_9DOF_GBY_KALMAN *pthisSV_9DOF_GBY_KALMAN, struct AccelSensor *pthisAccel, struct MagSensor *pthisMag, struct GyroSensor *pthisGyro, struct PressureSensor *pthisPressure, struct MagCalibration *pthisMagCal)
void iUpdateMagBuffer(struct MagBuffer *pthisMagBuffer, struct MagSensor *pthisMag, int32 loopcounter)
int8_t iMagBufferReadOnly
flag to denote that the magnetic measurement buffer is temporarily read only
The sensor_drv.h file contains sensor state and error definitions.
Provides function prototypes for driver level interfaces.
ssSetStatus_t * queue
queue status change for next regular interval
fpSpiReadPreprocessFn_t pReadPreprocessFN
conditionSensorReadings_t * conditionSensorReadings
preprocessing step for sensor fusion
int8_t installSensor(SensorFusionGlobals *sfg, struct PhysicalSensor *pSensor, uint16_t addr, uint16_t schedule, void *bus_driver, registerDeviceInfo_t *busInfo, initializeSensor_t *initialize, readSensor_t *read)
#define F_3DOF_B_BASIC
3DOF mag eCompass (vehicle/mag) algorithm selector - 0x0400 to include, 0x0000 otherwise ...
#define F_USING_ACCEL
nominally 0x0001 if an accelerometer is to be used, 0x0000 otherwise
#define F_6DOF_GY_KALMAN
6DOF accel and gyro (Kalman) algorithm selector - 0x2000 to include, 0x0000 otherwise ...
struct MagSensor Mag
magnetometer storage
SV_6DOF_GB_BASIC is the 6DOF basic accelerometer and magnetometer state vector structure.
Application-specific status subsystem.
This structure defines the device specific info required by register I/O.
int32_t loopcounter
counter incrementing each iteration of sensor fusion (typically 25Hz)
Quaternion derived from 3-axis mag only (auto compass algorithm)
#define F_3DOF_G_BASIC
3DOF accel tilt (accel) algorithm selector - 0x0200 to include, 0x0000 otherwise
void ARM_systick_enable(void)
float fuTPerCount
uT per count
applyPerturbation_t ApplyPerturbation
ApplyPerturbation is a reverse unit-step test function.
registeridlefunction_t idleFunction
Lower level sensor fusion interface.
void zeroArray(StatusSubsystem *pStatus, void *data, uint16_t size, uint16_t numElements, uint8_t check)
fpSpiWritePreprocessFn_t pWritePreprocessFN
void conditionSensorReadings(SensorFusionGlobals *sfg)
void * bus_driver
should be of type (ARM_DRIVER_I2C* for I2C-based sensors, ARM_DRIVER_SPI* for SPI) ...
void initializeFusionEngine(SensorFusionGlobals *sfg)
readSensors_t * readSensors
read all physical sensors
#define CHY
Used to access Y-channel entries in various data data structures.
struct PhysicalSensor * pSensors
a linked list of physical sensors
void setStatus(SensorFusionGlobals *sfg, fusion_status_t status)
void updateStatus(SensorFusionGlobals *sfg)
uint8_t iFIFOCount
number of measurements read from FIFO
void processMagData(SensorFusionGlobals *sfg)
void testStatus(SensorFusionGlobals *sfg)
The top level fusion structure.
#define F_USING_PRESSURE
nominally 0x0008 if altimeter is to be used, 0x0000 otherwise
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
float fBs[3]
averaged un-calibrated measurement (uT)
The sensor_fusion.h file implements the top level programming interface.
updateStatus_t * updateStatus
status=next status
int8_t readSensors(SensorFusionGlobals *sfg, uint16_t read_loop_counter)
Quaternion derived from full 9-axis sensor fusion.
struct PhysicalSensor * next
pointer to next sensor in this linked list
void fInvertMagCal(struct MagSensor *pthisMag, struct MagCalibration *pthisMagCal)
void addToFifo(union FifoSensor *sensor, uint16_t maxFifoSize, int16_t sample[3])
addToFifo is called from within sensor driver read functions
#define CHZ
Used to access Z-channel entries in various data data structures.
initializeFusionEngine_t * initializeFusionEngine
set sensor fusion structures to initial values
he ControlSubsystem encapsulates command and data streaming functions.
void ARM_systick_delay_ms(uint32 iSystemCoreClock, uint32 delay_ms)
readSensor_t * read
pointer to function to read sensor using the supplied drivers
ssSetStatus_t * set
change status immediately - no delay
initializeSensor_t * initialize
pointer to function to initialize sensor using the supplied drivers
void queueStatus(SensorFusionGlobals *sfg, fusion_status_t status)
void ApplyGyroHAL(struct GyroSensor *Gyro)
Apply the gyroscope Hardware Abstraction Layer.
#define F_USING_GYRO
nominally 0x0004 if a gyro is to be used, 0x0000 otherwise
The AccelSensor structure stores raw and processed measurements for a 3-axis accelerometer.
uint16_t isInitialized
Bitfields to indicate sensor is active (use SensorBitFields from build.h)
int8_t() readSensor_t(struct PhysicalSensor *sensor, struct SensorFusionGlobals *sfg)
ssUpdateStatus_t * update
make pending status active/visible
#define F_9DOF_GBY_KALMAN
9DOF accel, mag and gyro algorithm selector - 0x4000 to include, 0x0000 otherwise ...
void fInitializeMagCalibration(struct MagCalibration *pthisMagCal, struct MagBuffer *pthisMagBuffer)
registerDeviceInfo_t deviceInfo
I2C device context.
void clearFIFOs(SensorFusionGlobals *sfg)
Function to clear FIFO at the end of each fusion computation.
volatile uint8_t iPerturbation
test perturbation to be applied
ssUpdateStatus_t * test
unit test which simply increments to next state
updateStatus_t * testStatus
increment to next enumerated status value (test only)
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
This is the 3DOF basic accelerometer state vector structure.
bool isEnabled
true if the device is sampling
void fInvertAccelCal(struct AccelSensor *pthisAccel, struct AccelCalibration *pthisAccelCal)
function maps the accelerometer data fGs (g) onto precision calibrated and de-rotated data fGc (g)...
The GyroSensor structure stores raw and processed measurements for a 3-axis gyroscope.
void ApplyAccelHAL(struct AccelSensor *Accel)
Apply the accelerometer Hardware Abstraction Layer.
fusion_status_t
Application-specific serial communications system.
int16_t iBs[3]
averaged uncalibrated measurement (counts)
applyPerturbation_t * applyPerturbation
apply step function for testing purposes
uint16_t iFIFOExceeded
Number of samples received in excess of software FIFO size.
SV_9DOF_GBY_KALMAN is the 9DOF Kalman filter accelerometer, magnetometer and gyroscope state vector s...
struct MagCalibration MagCal
mag cal storage
Magnetic Calibration Structure.
setStatus_t * queueStatus
queue status change for next regular interval
volatile int8_t AccelCalPacketOn
variable used to coordinate accelerometer calibration
SV_3DOF_Y_BASIC structure is the 3DOF basic gyroscope state vector structure.
struct ControlSubsystem * pControlSubsystem
clearFIFOs_t * clearFIFOs
clear sensor FIFOs
StatusSubsystem() provides an object-like interface for communicating status to the user...